import requests
import os
import time
import json
import hashlib
import random
import re
import datetime
import logging  # 新增日志模块

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

def send_request(url, datas):
    session = requests.Session()
    session.adapters.DEFAULT_RETRIES = 5  # 设置重试次数
    session.keep_alive = False  # 关闭连接保持
    
    headers = {
        "Content-Type": "application/json",
        "Charset": "UTF-8"
    }
    
    try:
        # 序列化数据并编码
        send_data = json.dumps(datas, ensure_ascii=False)
        send_datas = send_data.encode("utf-8")
        
        # 拼接完整URL（补全HTTPS协议）
        api_url = f"https://oapi.dingtalk.com/robot/send?access_token={url}"
        response = session.post(api_url, headers=headers, data=send_datas)
        response.raise_for_status()  # 抛出HTTP错误
        logger.info(f"请求成功，响应内容：{response.text}")
        return response.text
    except requests.exceptions.RequestException as e:
        logger.error(f"发送请求失败：{str(e)}")
        raise

def get_ddmodel_datas(type_):
    
    if type_ == 1:
        return {
            "msgtype": "text",
            "text": {"content": ""},
            "at": {"atMobiles": [], "isAtAll": False}
        }
    elif type_ == 2:
        return {
            "msgtype": "markdown",
            "markdown": {"title": "", "text": ""},
            "at": {"isAtAll": False}
        }
    elif type_ == 3:
        return {
            "msgtype": "markdown",
            "markdown": {"title": "", "text": ""},
            "at": {"atMobiles": [], "isAtAll": False}
        }
    elif type_ == 4:
        return {
            "msgtype": "link",
            "link": {"text": "", "title": "", "picUrl": "", "messageUrl": ""}
        }
    else:
        raise ValueError("不支持的消息类型")

def query_alm(time_escape):  # 移除冗余参数parm
    """查询告警数据（优化参数逻辑）"""
    time_now = datetime.datetime.now()
    time_begin = time_now - datetime.timedelta(minutes=30)  # 修正时间计算方向
    
    str_time_now = time_now.strftime("%Y-%m-%d %H:%M:%S")
    str_time_begin = time_begin.strftime("%Y-%m-%d %H:%M:%S")
    time_stamp = int(round(time.time() * 1000))  # 修正乘法符号
    
    # 优化参数结构（修正JSON格式错误，添加引号）
    param_dict = {
        "alarmOrigin": "0",
        "alarmSenceId": "0",
        "asc": False,
        "fieldConditions": {
            "conditionList": [
                {"fieldId": "137", "not": False, "type": "eq", "value": "-1128953347", "values": [-1128953347]},
                {"fieldId": "90", "not": False, "type": "eq", "value": "532672528", "values": [532672528]},
                {"fieldId": "30", "not": False, "type": "like", "value": "OLT PON口收无光", "values": ["OLT PON口收无光"]}  # 移除测试注释
            ],
            "logicalAnd": True,
            "not": True
        },
        "statusBean": {
            "activeStatus": "1",  # 修正键名activeStatus1为activeStatus
            "fieldId": "68",
            "not": False,
            "status": [0, 1, 3]
        },
        "mConditionMaps": {},
        "fieldIds": [3, 15, 361, 178, 7, 36, 33, 138, 62, 4, 16, 18, 30, 92],
        "logicalAnd": True,
        "sessionId": time_stamp,
        "sortFieldId": "-1",
        "userId": "621392",
        "dateBean": {
            "endTime": str_time_now,
            "fieldId": "62",
            "not": False,
            "startTime": str_time_begin,
            "type": "type"  # 保留原始类型（如需动态值需进一步优化）
        },
        "defaultFieldIds": [64, 62, 68, 137, 33, 35, 7, 16, 30, 116, 23, 9, 4],
        "loginProvinceId": "-1128953347",
        "pageSize": "10000",
        "startIndex": "0"
    }
    
    headers = {
        "Host": "10.245.0.121:9011",  # 补全端口号
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0",
        "Accept": "application/json",
        "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
        "Content-Type": "application/json",
        "zoneId": "-1128953347",
        "Authorization": f"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3NDk0NjQyNTg5OTIsImlhdCI6MTc0OTQ1NzA1OCwidXNlcklkIjoiNzQ4ODQ0IiwianRpIjoiNzU2MmRhOGNiZmMwYmZmOTE3NTU0ZGZiZGIwODdiZGQwMmI1YmYyOSJ9.65NyIU5dH8SDwSSkChSHRZ5-qfW_u18tCJLPLgKJNlc"
    }
    
    session = requests.Session()
    session.adapters.DEFAULT_RETRIES = 5
    session.keep_alive = False
    
    # 补全URL协议和路径（假设为HTTP）
    url = "http://10.245.0.121:9011/filter/sysadminAlarmrecord-new-page"
    
    try:
        payload = json.dumps(param_dict, ensure_ascii=False)
        response = session.post(url, headers=headers, data=payload)
        response.raise_for_status()
        logger.info("获取告警数据成功")
        time.sleep(0.3)
        
        response_dict = response.json()  # 直接解析JSON
        total = response_dict.get("total", 0)  # 安全获取total值
        logger.info(f"总告警数：{total}")
        
        alarm_dict = {}
        for alarm in response_dict.get("data", []):  # 安全获取data列表
            eqp_label = alarm.get("eqp_label", {}).get("value", "未知设备")
            ne_label = alarm.get("ne_label", {}).get("value", "未知网元")
            key = f"{eqp_label}, {ne_label}"
            
            if key in alarm_dict:
                alarm_dict[key] += 1
            else:
                alarm_dict[key] = 1
        
        time.sleep(0.3)
        return alarm_dict
    except (requests.exceptions.RequestException, json.JSONDecodeError) as e:
        logger.error(f"查询告警失败：{str(e)}")
        raise

def send_tz(alarm_dict):
    """发送钉钉通知（优化告警逻辑）"""
    logger.info("开始处理告警通知")
    alert_content = "# 🚨 **超频PON口故障告警** 🚨\n\n"
    triggered = False
    
    for key, count in alarm_dict.items():
        if count >= 5:  # 支持阈值配置（当前阈值为5次）
            triggered = True
            alert_content += f"- **设备/网元**：{key}\n  - **告警次数**：{count}次\n\n"
    
    if triggered:
        # 获取markdown格式消息模板（type=3对应带@的markdown）
        msg_data = get_ddmodel_datas(3)
        msg_data["markdown"]["title"] = "【紧急】PON口故障告警"
        msg_data["markdown"]["text"] = alert_content
        
        # 从环境变量获取钉钉机器人Token（需提前配置）
        access_token = "b48d67f748e84d15ccca047e932c6eb8de30f8f10c054909896d368af1e41368"
        if not access_token:
            logger.error("未配置钉钉机器人Token，无法发送通知")
            return
        
        try:
            send_request(access_token, msg_data)
            logger.info("告警通知已发送")
        except Exception as e:
            logger.error(f"发送通知失败：{str(e)}")
    else:
        logger.info("当前无需要通知的告警")

if __name__ == "__main__":
    # 等待程序初始化（可根据实际需求调整）
    time.sleep(8)
    
    try:
        # 调用查询函数（修正参数传递，仅传递time_escape）
        alarm_dict = query_alm(2)  # 假设time_escape为2（需根据业务逻辑确认值）
        send_tz(alarm_dict)
    except Exception as e:
        logger.critical(f"程序运行失败：{str(e)}", exc_info=True)